/*
 *  Workspace window manager
 *  Copyright (c) 2015-2021 Sergii Stoian
 *
 *  WindowMaker miscelaneous functions
 *  Copyright (c) 1997-2003 Alfredo K. Kojima
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
 *  MA 02110-1301, USA.
 */

#include <X11/Xlib.h>
#include <stdlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <string.h>

#include "WM.h"

#include "xutil.h"

#include <core/WMcore.h>

static const char *requestCodes[] = {"DUMMY",
                                     "X_CreateWindow",
                                     "X_ChangeWindowAttributes",
                                     "X_GetWindowAttributes",
                                     "X_DestroyWindow",
                                     "X_DestroySubwindows",
                                     "X_ChangeSaveSet",
                                     "X_ReparentWindow",
                                     "X_MapWindow",
                                     "X_MapSubwindows",
                                     "X_UnmapWindow",
                                     "X_UnmapSubwindows",
                                     "X_ConfigureWindow",
                                     "X_CirculateWindow",
                                     "X_GetGeometry",
                                     "X_QueryTree",
                                     "X_InternAtom",
                                     "X_GetAtomName",
                                     "X_ChangeProperty",
                                     "X_DeleteProperty",
                                     "X_GetProperty",
                                     "X_ListProperties",
                                     "X_SetSelectionOwner",
                                     "X_GetSelectionOwner",
                                     "X_ConvertSelection",
                                     "X_SendEvent",
                                     "X_GrabPointer",
                                     "X_UngrabPointer",
                                     "X_GrabButton",
                                     "X_UngrabButton",
                                     "X_ChangeActivePointerGrab",
                                     "X_GrabKeyboard",
                                     "X_UngrabKeyboard",
                                     "X_GrabKey",
                                     "X_UngrabKey",
                                     "X_AllowEvents",
                                     "X_GrabServer",
                                     "X_UngrabServer",
                                     "X_QueryPointer",
                                     "X_GetMotionEvents",
                                     "X_TranslateCoords",
                                     "X_WarpPointer",
                                     "X_SetInputFocus",
                                     "X_GetInputFocus",
                                     "X_QueryKeymap",
                                     "X_OpenFont",
                                     "X_CloseFont",
                                     "X_QueryFont",
                                     "X_QueryTextExtents",
                                     "X_ListFonts",
                                     "X_ListFontsWithInfo",
                                     "X_SetFontPath",
                                     "X_GetFontPath",
                                     "X_CreatePixmap",
                                     "X_FreePixmap",
                                     "X_CreateGC",
                                     "X_ChangeGC",
                                     "X_CopyGC",
                                     "X_SetDashes",
                                     "X_SetClipRectangles",
                                     "X_FreeGC",
                                     "X_ClearArea",
                                     "X_CopyArea",
                                     "X_CopyPlane",
                                     "X_PolyPoint",
                                     "X_PolyLine",
                                     "X_PolySegment",
                                     "X_PolyRectangle",
                                     "X_PolyArc",
                                     "X_FillPoly",
                                     "X_PolyFillRectangle",
                                     "X_PolyFillArc",
                                     "X_PutImage",
                                     "X_GetImage",
                                     "X_PolyText8",
                                     "X_PolyText16",
                                     "X_ImageText8",
                                     "X_ImageText16",
                                     "X_CreateColormap",
                                     "X_FreeColormap",
                                     "X_CopyColormapAndFree",
                                     "X_InstallColormap",
                                     "X_UninstallColormap",
                                     "X_ListInstalledColormaps",
                                     "X_AllocColor",
                                     "X_AllocNamedColor",
                                     "X_AllocColorCells",
                                     "X_AllocColorPlanes",
                                     "X_FreeColors",
                                     "X_StoreColors",
                                     "X_StoreNamedColor",
                                     "X_QueryColors",
                                     "X_LookupColor",
                                     "X_CreateCursor",
                                     "X_CreateGlyphCursor",
                                     "X_FreeCursor",
                                     "X_RecolorCursor",
                                     "X_QueryBestSize",
                                     "X_QueryExtension",
                                     "X_ListExtensions",
                                     "X_ChangeKeyboardMapping",
                                     "X_GetKeyboardMapping",
                                     "X_ChangeKeyboardControl",
                                     "X_GetKeyboardControl",
                                     "X_Bell",
                                     "X_ChangePointerControl",
                                     "X_GetPointerControl",
                                     "X_SetScreenSaver",
                                     "X_GetScreenSaver",
                                     "X_ChangeHosts",
                                     "X_ListHosts",
                                     "X_SetAccessControl",
                                     "X_SetCloseDownMode",
                                     "X_KillClient",
                                     "X_RotateProperties",
                                     "X_ForceScreenSaver",
                                     "X_SetPointerMapping",
                                     "X_GetPointerMapping",
                                     "X_SetModifierMapping",
                                     "X_GetModifierMapping",
                                     "X_NoOperation"};

void FormatXError(Display *dpy, XErrorEvent *error, char *buffer, int size)
{
  int i, p;

  XGetErrorText(dpy, error->error_code, buffer, size);
  i = strlen(buffer);
  if (i > size - 100)
    return;
  buffer += i;
  if (error->request_code >= wlengthof(requestCodes)) {
    sprintf(buffer, "\n	Request code: %i\n", error->request_code);
  } else {
    sprintf(buffer, "\n	Request code: %i %s\n", error->request_code,
            requestCodes[error->request_code]);
  }
  i += p = strlen(buffer);
  if (i > size - 40)
    return;
  buffer += p;
  sprintf(buffer, "	Request minor code: %i\n", error->minor_code);
  i += p = strlen(buffer);
  if (i > size - 30)
    return;
  buffer += p;
  sprintf(buffer, "	Resource ID: 0x%x\n", (unsigned int)error->resourceid);
  i += p = strlen(buffer);
  if (i > size - 30)
    return;
  buffer += p;
  sprintf(buffer, "	Error serial: %li\n", error->serial);
  return;
}
